moddbfandomcom-20200213-history
C:SPL tutorials
Introduction Have you ever wondered how to develop plug-ins for multiple platforms like Windows AND Linux with the same code? Then you should take a closer look at the Simple Plug-in Layer (SPL) Library! About this Library The SPL (Simple Plug-in Layer) library is an open source SDK (LGPL license) for plug-in development. With SPL, you can extend every application written in C/C++ to use your own plug-ins, SPL will do all the managing, loading and unloading stuff for you. Additionally, the whole framework is fully multi-platform capable, so you don't have to develop multiple versions of the same plug-in for platforms provided by SPL. This library was developed by Andreas Loeffler and René Stuhr. Please visit here for updates and more useful stuff regarding SPL. Features * Open Source, uses LGPL license * Free, costs absolutely nothing, even for commercial use * Platform independent architecture * Implementations for Linux and Win32 available, more platforms coming soon ... * Full Doxygen-/Javadoc-compatible documentation * Optional macros for fast and easy plug-in development * Variable plug-in arguments for extensible APIs * Thread-safety for complex applications * Uses STL library for stable and portable containers * Object-oriented design, easy to extend * Customizable to 32- or 64-bit systems * Completely written in C++, no other dependencies except STL needed * Buildable as static/shared library or DLL (only Win32) * Various examples for all platforms explaining the development step by step * Source code written in uniform style Overview SPL is divided in two parts: Functions / classes for applications that want to use plug-ins, and the plug-in development side. The plug-in development side offers macros you can use optionally to speed up your plug-in development. A plug-in consists of 4 simple C-functions, which all except one can be implemented as "default-functions" without any code behind it, using SPL's macros: * GetInfo * Initialize * Run (cannot be used as default-function) * Shutdown What does "default-function" mean, you might ask now? A default-function is a simple function without any code in it. Since SPL requires these 4 functions in any case, you could use SPL's macros for implementing it. If you want to use one of these functions in a special way you want, just don't use the function-macro and implement that function for yourself. For these 3 functions, SPL uses the following macros: SPL_IMPLEMENT_PLUGIN_GETINFO(); SPL_IMPLEMENT_PLUGIN_INITIALIZE(); SPL_IMPLEMENT_PLUGIN_SHUTDOWN(); So, why doesn't the Run function have such a macro? Hmmm, well, if we would have such a macro, the Run function would be implemented by default with no code, so the plug-in does nothing :-) Note: If you want to use/compile your plug-in with Windows, you need two additional macros provided by SPL, they're called. SPL_DEFINE_PLUGIN_EXPORTS(); SPL_DEFINE_PLUGIN_DLLMAIN(); These two macros provide some Windows-specific code which is not used by other platforms like Linux, for example. Don't worry about it, you can put them safely into your plug-in, it does not matter if you want to compile/use your plug-in on Linux platforms, SPL does all the stuff internally for you, so you won't have to change anything to compile AND use your plug-ins on different platforms! A "Hello-World" Plug-in Let's start with a very simple "Hello-World" plug-in. This example is also included in the SPL package. Our goal is a simple plug-in that compiles / runs on Windows and Linux without doing any changes in the source code when "porting" it. Okay, actually you don't have to "port" anything ;-) Have a look at the header file: #if SPL_PLATFORM SPL_PLATFORM_WIN32 #include #endif SPL_DEFINE_PLUGIN_EXPORTS(); SPL_DEFINE_PLUGIN_INFO( 1, ///< The build number. 1, ///< The major version (e.g. 1.xx). 0, ///< The minor version (e.g. 0.10). true, ///< Does this plugin show its arguments to the public? "plHelloWorld", ///< The plugin's name. "United Bytes", ///< The plugin's vendor. "Hello world, our first plugin!", ///< The plugin's general description. "Simple test plugin! :-)", ///< The plugin's additional description. "http://www.unitedbytes.de", ///< The plugin vendor's homepage. "info@unitedbytes.de", ///< The plugin vendor's email address. "ConsoleExampleAPI" ); ///< The plugin's UUID. That's really all you need in your header file. We already discussed the SPL_DEFINE_PLUGIN_EXPORTS(); macro, so let's go to the macro. SPL_DEFINE_PLUGIN_INFO(); This macro derives a class from slcPluginInfo, which is responsible to hold the plug-in's information like name, version, build number, vendor etc., and creates a global instance called g_pluginInfo. This global object is required for all default-function macros of SPL. Note for hardcore-coders: You don't need any of SPL's macros to get it working, a simple example on how to implement a plug-in without all macros is included in the SPL package. Since our header file is now complete, let's step into our .cpp file! #include "plHelloWorld.h" SPL_DEFINE_PLUGIN_DLLMAIN(); SPL_IMPLEMENT_PLUGIN_GETINFO(); SPL_PLUGIN_API bool SPL_INIT_NAME_CODE( slcPluginArgs* a_pPluginArgs ) { printf( "HelloWorld: Hi there! Here we could initialize something!\n" ); return true; } SPL_PLUGIN_API bool SPL_RUN_NAME_CODE( slcPluginArgs* a_pPluginArgs ) { printf( "HelloWorld: Hi, this is the plugin's run function!\n" ); return true; } SPL_PLUGIN_API bool SPL_SHUTDOWN_NAME_CODE( slcPluginArgs* a_pPluginArgs ) { printf( "HelloWorld: Bye, bye world, this is the shutdown function.\n" ); return true; } Looks very simple, doesn't it? You may notice that I don't use any "default-function" macros (except for the GetInfo function) in here, since I want to present how you can use all functions (again, except GetInfo) on your own. "Hm, okay, sounds good, but when are all these functions called?" I hear you whisper ..that's a good question! The reason why almost nobody would implement an own version of GetInfo is that this function basically does nothing else than returning a pointer to the plug-in information structure we filled in the header by using the macro SPL_DEFINE_PLUGIN_INFO(). The Initialize function is called when a plug-in is successfully loaded, GetInfo is called manually from the user's code if he wants to get more information about the plug-in, Run contains the actual plug-in code, Shutdown is either called manually by the user if his program ends or it's done by SPL's destructor to give all plug-ins a chance to clean themselves up. Various examples using SPL are included in the SDK, a Doxygen-generated documentation for all parameters and functions is included, too. Builds for Microsoft .NET 2003, Microsoft Visual Studio 6.0 and Linux (GCC) are included. Category:C Category:Tutorial